﻿using Edu.Abstracts;
using Edu.Contracts;
using Edu.Entitys;
using Edu.Utilities;
using Microsoft.AspNetCore.Authorization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Linq;

namespace Edu.Services
{
    public class UserAchievementAppService : ApplicationService, IUserAchievementAppService
    {
        public IAsyncQueryableExecuter AsyncQueryableExecuter { get; set; }
        protected IRepository<AppUserAchievement, Guid> Repository { get; }

        private IRepository<AppAchievement, Guid> achievementRepository;
        private IAppUserRepository appUserRepository;

        public UserAchievementAppService(IRepository<AppUserAchievement, Guid> repository, IRepository<AppAchievement, Guid> achievementRepository, IAppUserRepository appUserRepository)
        {
            Repository = repository;
            this.achievementRepository = achievementRepository;
            this.appUserRepository = appUserRepository;
            AsyncQueryableExecuter = DefaultAsyncQueryableExecuter.Instance;
        }

        public async Task<UserAchievementDto> GetAsync(Guid id)
        {
            var entity = await GetEntityByIdAsync(id);

            return new UserAchievementDto()
            {
                Id = entity.Id,
                UserName = entity.User.UserName,
                AchievementName = entity.Achievement.Name,
                AchievementIcon = entity.Achievement.ActiveIcon,
            };
        }

        [AllowAnonymous]
        public async Task<UserAchievementDto> CreateAsync(UserAchievementCreateDto input)
        {
            var achievementId = Guid.Parse(input.AchievementId);


            var user = await appUserRepository.FindByPhoneNumberAsync(input.PhoneNumber);
            if (user == null)
            {
                throw new UserFriendlyException("用户不存在");
            }
            var exist = Repository.Any(
              u => u.UserId == user.Id && u.AchievementId == achievementId);

            if (exist)
            {
                throw new UserFriendlyException("用户已有该勋章");
            }

            var achievement = await achievementRepository.GetAsync(achievementId);

            if (achievement == null)
            {
                throw new UserFriendlyException("成就不存在");
            }

            var entity = new AppUserAchievement()
            {
                Id = this.GuidGenerator.Create(),
                UserId = user.Id,
                CreatedTime = DateTimeOffset.UtcNow,
                Progress = 0,
                AchievementId = achievementId
            };
            await Repository.InsertAsync(entity, autoSave: true);
            return new UserAchievementDto()
            {
                Id = entity.Id,
                UserName = user.UserName,
                AchievementName = achievement.Name,
                AchievementIcon = achievement.ActiveIcon
            };

        }

        public async Task DeleteAsync(Guid id)
        {
            await Repository.DeleteAsync(id);
        }

        public async Task<PagedResultDto<UserAchievementDto>> GetListAsync(PagedAndSortedResultRequestDto input)
        {
            var query = CreateFilteredQuery(input);

            var totalCount = await AsyncQueryableExecuter.CountAsync(query);

            query = query.ApplySorting(input);
            query = query.ApplyPaging(input);

            var entities = await AsyncQueryableExecuter.ToListAsync(query);

            var result = new List<UserAchievementDto>();
            foreach (var item in entities)
            {
                var user = await appUserRepository.GetAsync(item.UserId);
                var achievement = await achievementRepository.GetAsync(item.AchievementId);

                result.Add(new UserAchievementDto
                {
                    Id = item.Id,
                    UserName = user.UserName,
                    AchievementName = achievement.Name,
                    AchievementIcon = achievement.ActiveIcon
                });
            }
            return new PagedResultDto<UserAchievementDto>(
                 totalCount,
                 result
            );
        }


        protected virtual Task<AppUserAchievement> GetEntityByIdAsync(Guid id)
        {
            return Repository.GetAsync(id);
        }

        protected virtual IQueryable<AppUserAchievement> CreateFilteredQuery(PagedAndSortedResultRequestDto input)
        {
            return Repository;
        }

        public int GetAchievementCount(Guid id)
        {
            return Repository.Count(a => a.UserId == id && a.CreatedTime != null);
        }


        public async Task HandlerAbilityGaoJie(AppStudent student)
        {
            await this.nengligaojie(student);
            await this.jiaodaoyoufang(student);
        }

        //至少两项能力晋升到高阶  能力高阶
        private async Task nengligaojie(AppStudent student)
        {
            var guid = Guid.Parse(EnumUtils.StringValueOf(AchievementTypes.能力高阶));
            var achievement = await this.GetOrAddUserAchievement(guid, student.UserId);
            if (achievement.CreatedTime != null)
            {
                return;
            }
            achievement.Progress++;
            if (achievement.Progress >= 2)
            {
                achievement.CreatedTime = DateTimeOffset.UtcNow;
            }

            await this.Repository.UpdateAsync(achievement, autoSave: true);
        }

        //所有徒弟中,能力累计10次进阶到高阶  教导有方
        private async Task jiaodaoyoufang(AppStudent student)
        {
            var guid = Guid.Parse(EnumUtils.StringValueOf(AchievementTypes.教导有方));
            var achievement = await this.GetOrAddUserAchievement(guid, student.TeacherId);
            if (achievement.CreatedTime != null)
            {
                return;
            }
            achievement.Progress++;
            if (achievement.Progress >= 10)
            {
                achievement.CreatedTime = DateTimeOffset.UtcNow;
            }
            await this.Repository.UpdateAsync(achievement, autoSave: true);
        }

        public async Task HandlerAbilityXunZhang(AppStudent student)
        {
            await this.rongyuxunzhang(student);
        }


        //累计获得勋章12个  荣誉勋章
        private async Task rongyuxunzhang(AppStudent student)
        {
            var guid = Guid.Parse(EnumUtils.StringValueOf(AchievementTypes.荣誉勋章));
            var achievement = await this.GetOrAddUserAchievement(guid, student.UserId);
            if (achievement.CreatedTime != null)
            {
                return;
            }
            achievement.Progress++;

            if (achievement.Progress >= 12)
            {
                achievement.CreatedTime = DateTimeOffset.UtcNow;
            }

            await this.Repository.UpdateAsync(achievement, autoSave: true);
        }




        public async Task<AppUserAchievement> GetOrAddUserAchievement(Guid achievementId, Guid userId)
        {
            var result = this.Repository.Where(s => s.AchievementId == achievementId && s.UserId == userId)
                .FirstOrDefault();

            if (result == null)
            {
                result = await this.Repository.InsertAsync(new AppUserAchievement()
                {
                    Id = Guid.NewGuid(),
                    UserId = userId,
                    Progress = 0,
                    AchievementId = achievementId
                }, true);
            }
            return result;
        }

    }
}
